home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 June / EnterCD 06_2004.iso / Internet / Bloomba 1.0.6 / Bloomba1706Installer.exe / saproxy / Disk1 / data1.cab / rules / 20_head_tests.cf < prev    next >
Encoding:
Text File  |  2004-03-01  |  37.1 KB  |  760 lines

  1. # SpamAssassin rules file: header tests
  2. #
  3. # Please don't modify this file as your changes will be overwritten with
  4. # the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead.
  5. # See 'perldoc Mail::SpamAssassin::Conf' for details.
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of either the Artistic License or the GNU General
  9. # Public License as published by the Free Software Foundation; either
  10. # version 1 of the License, or (at your option) any later version.
  11. #
  12. # See the file "License" in the top level of the SpamAssassin source
  13. # distribution for more details.
  14. #
  15. ###########################################################################
  16.  
  17. require_version @@VERSION@@
  18.  
  19. header NO_REAL_NAME        From =~ /^["\s]*\<?\S+\@\S+\>?\s*$/
  20. describe NO_REAL_NAME        From: does not include a real name
  21.  
  22. header FROM_ENDS_IN_NUMS    From =~ /\d\d\@/
  23. describe FROM_ENDS_IN_NUMS    From: ends in numbers
  24.  
  25. header FROM_STARTS_WITH_NUMS    From =~ /^\d\d/
  26. describe FROM_STARTS_WITH_NUMS    From: starts with nums
  27.  
  28. header FROM_HAS_MIXED_NUMS    From =~ /\d+[a-z]+\d+\S*\@/i
  29. describe FROM_HAS_MIXED_NUMS    From: contains numbers mixed in with letters
  30.  
  31. # bug 637, more specific FROM_HAS_MIXED_NUMS, less FPs
  32. header FROM_HAS_MIXED_NUMS2    From =~ /\w{2,}\d{4,}[a-z]{1,2}\d{2,}\@/i
  33. describe FROM_HAS_MIXED_NUMS2    From address matches known spammer format
  34.  
  35. # idea from Robert Menschel <RMSA@Menschel.net>
  36. header FROM_HAS_MIXED_NUMS3    From:addr =~ /^[a-z]+\d+[a-z]+\d+[a-z]+\w*\@/i
  37. describe FROM_HAS_MIXED_NUMS3    From: contains numbers mixed in with letters
  38.  
  39. # Faked addresses tend to come from big public sites.  Stats show that
  40. # 5 digits is enough to get a 1.0 s/o ratio; 4 is too low (probably due
  41. # to folks called "jmason2002@yahoo.com" for example).
  42. header ADDR_NUMS_AT_BIGSITE    ALL =~ /^(To|From|Cc|Reply-To):\s*<?\S+\d{5,}\@(?:aol|bigfoot|compuserve|excite|hotmail|juno|prodigy|yahoo)\.(?:com|net|org)/mi
  43. describe ADDR_NUMS_AT_BIGSITE    Uses an address with lots of numbers, at a big ISP
  44.  
  45. header __FROM_JUST_NUMBER       From:addr =~ /^\d+\@/
  46. header __FROM_PHONE             From:addr =~ /^\d{3}(?:[-.]?\d{3}[-.]?\d{4}|\d{7})\@/
  47. meta FROM_ALL_NUMS              (__FROM_JUST_NUMBER && !__FROM_PHONE)
  48. describe FROM_ALL_NUMS          From an address that is all numbers (non-phone)
  49.  
  50. header FROM_OFFERS        From:addr =~ /\@\S*offers(?![eo]n\b)/i
  51. describe FROM_OFFERS        From address is "at something-offers"
  52.  
  53. header FROM_NO_USER        From =~ /(?:^\@|<\@| \@[^\)<]*$|<>)/ [if-unset: unset@unset.unset]
  54. describe FROM_NO_USER        From: has no local-part before @ sign
  55.  
  56. header TO_NO_USER        To =~ /(?:^\@|<\@| \@[^\)<]*$|<>)/ [if-unset: unset@unset.unset]
  57. describe TO_NO_USER        To: has no local-part before @ sign
  58.  
  59. header TO_HAS_SPACES            To:addr =~ /\s/
  60. describe TO_HAS_SPACES          To: address contains spaces
  61.  
  62. header TO_EMPTY            To =~ /^\s*$/ [if-unset: UNSET]
  63. describe TO_EMPTY        To: is empty
  64.  
  65. header REPLY_TO_EMPTY        Reply-To =~ /^\s*$/ [if-unset: UNSET]
  66. describe REPLY_TO_EMPTY        Reply-To: is empty
  67.  
  68. header REPLY_TO_ULINE_NUMS    Reply-To =~ /_\S?(?:[a-z]+\w*?\d+|\d+\w*?[a-z]+)\w*\@/i [if-unset: UNSET]
  69. describe REPLY_TO_ULINE_NUMS  Reply-To: has an underline and numbers/letters
  70.  
  71. # You don't want to let this match "'user@foo.bar'" <user@foo.bar>
  72. # (note single quotes) because some legitimate mailers seem to do that.
  73. header TO_ADDRESS_EQ_REAL    To =~ /^\s*"([^"@]+\@[^"@]+)"\s+<\1>\s*$/i
  74. describe TO_ADDRESS_EQ_REAL    To: repeats address as real name
  75.  
  76. # NOTE: this is what 100% valid undisclosed-recipients mails look like.
  77. # If this gets a high score, that's a bug!
  78. header UNDISC_RECIPS        To =~ /^undisclosed-recipients?:\s*;$/
  79. describe UNDISC_RECIPS        Valid-looking To "undisclosed-recipients"
  80.  
  81. # also 100% valid
  82.  
  83. header FAKED_UNDISC_RECIPS    To =~ /undisclosed[_ ]*recipient(?:s[^:]|[^s])/i
  84. describe FAKED_UNDISC_RECIPS    Faked To "Undisclosed-Recipients"
  85.  
  86. header PLING_QUERY        Subject =~ /\?.*!|!.*\?/
  87. describe PLING_QUERY        Subject has exclamation mark and question mark
  88.  
  89. header SUBJ_HAS_UNIQ_ID        eval:check_for_unique_subject_id()
  90. describe SUBJ_HAS_UNIQ_ID    Subject contains a unique ID
  91.  
  92. header SUBJ_HAS_SPACES        Subject =~ /(?:\s{6}|\t\s|\s\t)\S/
  93. describe SUBJ_HAS_SPACES    Subject contains lots of white space
  94.  
  95.  
  96. header SUBJ_ALL_CAPS        eval:subject_is_all_caps()
  97. describe SUBJ_ALL_CAPS        Subject is all capitals
  98.  
  99. # (allow this test to pass if there's no Message-Id header)
  100. header MSGID_HAS_NO_AT        MESSAGEID !~ /\@/ [if-unset: NO@MSGID]
  101. describe MSGID_HAS_NO_AT    Message-Id has no @ sign
  102.  
  103. header MSGID_SPAM_1        MESSAGEID =~ /<[0-9a-f]{12,12}\$[0-9a-f]{8,8}\$[0-9a-f]{8,8}\@>/
  104. describe MSGID_SPAM_1        Message-Id generated by a spam tool
  105.  
  106. # a good spamsign from another list
  107. header MSGID_SPAM_6LETTER    MESSAGEID =~ /<[0-9][0-9][0-9][a-f]..[a-f]..[a-f].[a-f]\$[0-9a-f]{4}[a-f].[a-f].\$.[a-f][a-f]..[a-f][a-f].\@[a-z]{6}>/
  108. describe MSGID_SPAM_6LETTER    Spam tool Message-Id: (6-letter variant)
  109.  
  110. header MSGID_SPAM_99X9XX99    MESSAGEID =~ /^<\d\d\d\d\d\d[a-z]\d[a-z][a-z]\d\d\$[a-z][a-z][a-z]\d\d\d\d\d\$\d\d\d\d\d\d\d\d\@/
  111. describe MSGID_SPAM_99X9XX99    Spam tool Message-Id: (99x9xx99 variant)
  112.  
  113. header MSGID_SPAM_ZEROES    MESSAGEID =~ /<0000[0-9a-f]{8}\$0000[0-9a-f]{4}\$0000[0-9a-f]{4}\@/
  114. describe MSGID_SPAM_ZEROES    Spam tool Message-Id: (12-zeroes variant)
  115.  
  116. header MSGID_3_DOLLARS        MESSAGEID =~ /^<?(?:\d+\$){3}\d+\@/m
  117. describe MSGID_3_DOLLARS    Spam tool Message-Id: (3-dollars variant)
  118. header MSGID_4NUMS_DOLLAR    MESSAGEID =~ /^<?\d{4}\$\w+\@/m
  119. describe MSGID_4NUMS_DOLLAR    Spam tool Message-Id: (4-num-dollar variant)
  120.  
  121. header RCVD_6_CAPS_ESMTP_ID    Received =~ /from \[\d+\.\d+\.\d+\.\d+\] by\s+\S+\s+with\s+ESMTP\s+id\s+[A-Z]{6}\;/
  122. describe RCVD_6_CAPS_ESMTP_ID    Spam tool Received: (6-caps ESMTP ID variant)
  123.  
  124. header MSGID_NO_HOST            MESSAGEID =~ /\@>(?:$|\s)/m
  125. describe MSGID_NO_HOST         Message-Id has no hostname
  126.  
  127. header MSGID_OUTLOOK_INVALID    eval:check_outlook_message_id()
  128. describe MSGID_OUTLOOK_INVALID    Message-Id is fake (in Outlook Express format)
  129.  
  130. ###########################################################################
  131.  
  132. header MSGID_FROM_MTA_SHORT    eval:mta_added_message_id('short')
  133. describe MSGID_FROM_MTA_SHORT    Message-Id was added by a relay
  134.  
  135. header MSGID_FROM_MTA_LATER    eval:mta_added_message_id('later')
  136. describe MSGID_FROM_MTA_LATER    Message-Id was added by a relay
  137.  
  138. header MSGID_FROM_MTA_BACKUP    eval:mta_added_message_id('backup')
  139. describe MSGID_FROM_MTA_BACKUP    Message-Id was added by a relay
  140. tflags MSGID_FROM_MTA_BACKUP    net
  141.  
  142. header __MSGID_BEFORE_RECEIVED        ALL =~ /\nMessage-Id:.*\nReceived:/si
  143. header __MSGID_BEFORE_OKAY        Message-Id =~ /\@[a-z0-9.-]+\.(?:yahoo|wanadoo)(?:\.[a-z]{2,3}){1,2}>/
  144. meta MSGID_FROM_MTA_HEADER        (__MSGID_BEFORE_RECEIVED && !__MSGID_BEFORE_OKAY)
  145. describe MSGID_FROM_MTA_HEADER    Message-Id was added by a relay
  146.  
  147. header MSGID_FROM_MTA_HOTMAIL    Message-Id =~ /<MC\d{1,2}-F{1,2}\w{21,22}\@\S*hotmail\.com>/
  148. describe MSGID_FROM_MTA_HOTMAIL    Message-Id was added by a hotmail.com relay
  149.  
  150. ###########################################################################
  151.  
  152. header DATE_SPAMWARE_Y2K    Date =~ /^[A-Z][a-z]{2}, \d\d [A-Z][a-z]{2} [0-6]\d \d\d:\d\d:\d\d [A-Z]{3}$/
  153. describe DATE_SPAMWARE_Y2K    Date header uses unusual Y2K formatting
  154.  
  155. header INVALID_DATE        Date !~ /^\s*(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), )?[0-3 ]?[0-9] (?:Jan|Feb|Ma[ry]|Apr|Ju[nl]|Aug|Sep|Oct|Nov|Dec) (?:[12][901])?[0-9]{2} [0-2][0-9](?:\:[0-5][0-9]){1,2} (?:[+-][0-9]{4}|UT|[A-Z]{2,3}T)(?:\s+\(.*\))?\s*$/ [if-unset: Wed, 31 Jul 2002 16:41:57 +0200]
  156. describe INVALID_DATE        Invalid Date: header (not RFC 2822)
  157.  
  158. # allow +1300, NZ timezone
  159. header INVALID_DATE_TZ_ABSURD    Date =~ /[-+](?:1[4-9]\d\d|[2-9]\d\d\d)$/
  160. describe INVALID_DATE_TZ_ABSURD    Invalid Date: header (timezone does not exist)
  161.  
  162. header DATE_YEAR_ZERO_FIRST    Date =~ /[nbrylgptvc]\s+0\d\d\d(?:\s|$)/
  163. describe DATE_YEAR_ZERO_FIRST    Invalid Date: year begins with zero
  164.  
  165. header DATE_IN_PAST_03_06    eval:check_for_shifted_date('-6', '-3')
  166. describe DATE_IN_PAST_03_06    Date: is 3 to 6 hours before Received: date
  167.  
  168. header DATE_IN_PAST_06_12    eval:check_for_shifted_date('-12', '-6')
  169. describe DATE_IN_PAST_06_12    Date: is 6 to 12 hours before Received: date
  170.  
  171. header DATE_IN_PAST_12_24    eval:check_for_shifted_date('-24', '-12')
  172. describe DATE_IN_PAST_12_24    Date: is 12 to 24 hours before Received: date
  173.  
  174. header DATE_IN_PAST_24_48    eval:check_for_shifted_date('-48', '-24')
  175. describe DATE_IN_PAST_24_48    Date: is 24 to 48 hours before Received: date
  176.  
  177. header DATE_IN_PAST_48_96    eval:check_for_shifted_date('-96', '-48')
  178. describe DATE_IN_PAST_48_96    Date: is 48 to 96 hours before Received: date
  179.  
  180. header DATE_IN_PAST_96_XX    eval:check_for_shifted_date('undef', '-96')
  181. describe DATE_IN_PAST_96_XX    Date: is 96 hours or more before Received: date
  182.  
  183. header DATE_IN_FUTURE_03_06    eval:check_for_shifted_date('3', '6')
  184. describe DATE_IN_FUTURE_03_06    Date: is 3 to 6 hours after Received: date
  185.  
  186. header DATE_IN_FUTURE_06_12    eval:check_for_shifted_date('6', '12')
  187. describe DATE_IN_FUTURE_06_12    Date: is 6 to 12 hours after Received: date
  188.  
  189. header DATE_IN_FUTURE_12_24    eval:check_for_shifted_date('12', '24')
  190. describe DATE_IN_FUTURE_12_24    Date: is 12 to 24 hours after Received: date
  191.  
  192. header DATE_IN_FUTURE_24_48    eval:check_for_shifted_date('24', '48')
  193. describe DATE_IN_FUTURE_24_48    Date: is 24 to 48 hours after Received: date
  194.  
  195. header DATE_IN_FUTURE_48_96    eval:check_for_shifted_date('48', '96')
  196. describe DATE_IN_FUTURE_48_96    Date: is 48 to 96 hours after Received: date
  197.  
  198. header DATE_IN_FUTURE_96_XX    eval:check_for_shifted_date('96', 'undef')
  199. describe DATE_IN_FUTURE_96_XX    Date: is 96 hours or more after Received: date
  200.  
  201. header ADVERT_CODE        Subject =~ /^\W*ADV\b/i
  202. describe ADVERT_CODE        Subject: starts with advertising tag
  203.  
  204. header ADVERT_CODE2        Subject =~ /\w.*\b(?!ADV\.)A\s*D\s*V\b/i
  205. describe ADVERT_CODE2        Subject: contains advertising tag
  206.  
  207. ###########################################################################
  208. # illegal characters that should be MIME encoded
  209. # might want to exempt users using languages that don't use Latin
  210. # alphabets, but do it in the eval
  211.  
  212. header SUBJ_ILLEGAL_CHARS    eval:check_illegal_chars('Subject','0.00','2')
  213. describe SUBJ_ILLEGAL_CHARS    Subject contains too many raw illegal characters
  214.  
  215. header FROM_ILLEGAL_CHARS    eval:check_illegal_chars('From','0.20','2')
  216. describe FROM_ILLEGAL_CHARS    From contains too many raw illegal characters
  217.  
  218. header HEAD_ILLEGAL_CHARS    eval:check_illegal_chars('ALL','0.005','2')
  219. describe HEAD_ILLEGAL_CHARS    Header contains too many raw illegal characters
  220.  
  221. ###########################################################################
  222. # ADV tags in non-English languages
  223.  
  224. # alan premselaar <alien@12inch.com>, see SpamAssassin-talk list 2003-03
  225. # quinlan: 2003-03-23 here are more generic Japanese iso-2022-jp codes
  226. # ("not yet acceptance" or "email") + "announcement"
  227. # FWIW, according to Peter Evans, this should be sufficient to catch the
  228. # UCE tag and a common attempt at evasion (using the "sue" instead of
  229. # "mi" Chinese character).
  230. header JAPANESE_UCE_SUBJECT    Subject =~ /\e\$B.*(?:L\$>5Bz|EE;R%a!<%k)9-9p/
  231. describe JAPANESE_UCE_SUBJECT    Subject contains a Japanese UCE tag
  232.  
  233. # quinlan: "advertisement" in Russian KOI8-R
  234. header RUSSIAN_UCE_SUBJECT    Subject =~ /\xf0\xe5\xea\xeb\xe0\xec\xf3/
  235. describe RUSSIAN_UCE_SUBJECT    Subject contains a Russian UCE tag
  236.  
  237. # Korean UCE Subject: lines are usually 8-bit, but are occasionally encoded
  238. # with quoted-printable or base64.
  239. #
  240. # \xbc\xba\xc0\xce means "adult"
  241. # \xb1\xa4\xb0\xed means "advertisement"
  242. # \xc1\xa4\xba\xb8 means "information"
  243. # \xc8\xab\xba\xb8 means "publicity"
  244. #
  245. # Each two byte sequence is one Korean letter; the spaces and periods are
  246. # sometimes used to obscure the words.  \xb1\xa4\xb0\xed is the most common
  247. # tag and is sometimes very obscured so we look harder.
  248. #
  249. header KOREAN_UCE_SUBJECT    Subject =~ /[({[<][. ]*(?:\xbc\xba[. ]*\xc0\xce[. ]*)?(?:\xb1\xa4(?:[. ]*|[\x00-\x7f]{0,3})\xb0\xed|\xc1\xa4[. ]*\xba\xb8|\xc8\xab[. ]*\xba\xb8)[. ]*[)}\]>]/
  250. describe KOREAN_UCE_SUBJECT    Subject: contains Korean unsolicited email tag
  251.  
  252. ###########################################################################
  253.  
  254. header FRIEND_AT_PUBLIC        To =~ /(?:yourdomain|you|your|(?<!re)public)\.(?:com|org|net)/i
  255. describe FRIEND_AT_PUBLIC    sent to you@you.com or similar
  256.  
  257. header FRIEND_PUBLIC        ALL =~ /^(?:to|cc|from):.*friend\@public\.com/im
  258. describe FRIEND_PUBLIC        sent from or to friend@public.com
  259.  
  260. header DOMAINS_CHEAP        Subject =~ /(?:new extensions|domain names) now only \$\s*\d+/i
  261. describe DOMAINS_CHEAP        Subject: domain names are cheap
  262.  
  263. header DOMAIN_SUBJECT        Subject =~ /(?:\s(?:\.|dot\s+)(?:info|biz|name)|domain)\b.*\b(?:extension|info|regist(?:ry|ration|er)|submission)/i
  264. describe DOMAIN_SUBJECT        Subject: domain registration spam subject
  265.  
  266. header NO_DNS_FOR_FROM        eval:check_for_from_dns()
  267. describe NO_DNS_FOR_FROM    Domain in From header has no MX or A DNS records
  268. tflags NO_DNS_FOR_FROM          net
  269.  
  270. header FROM_AND_TO_SAME        eval:check_for_from_to_same()
  271. describe FROM_AND_TO_SAME    From and To are the same, but not exactly
  272.  
  273. header MDAEMON_2_7_4        Received =~ /with SMTP .MDaemon.v2.7.SP4.R./
  274. describe MDAEMON_2_7_4        Received via buggy SMTP server (MDaemon 2.7.4SP4R)
  275.  
  276. header FORGED_RCVD_HELO        eval:check_for_forged_received_helo()
  277. describe FORGED_RCVD_HELO    Received: contains a forged HELO
  278.  
  279. header RCVD_NUMERIC_HELO    Received =~ /helo[= ]\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/i
  280. describe RCVD_NUMERIC_HELO    Received: contains a numeric HELO
  281.  
  282. header FAKED_IP_IN_RCVD        Received =~ /from [-0-9a-z\._]+_\[\d+\.\d+\.\d+\.\d+\] /i
  283. describe FAKED_IP_IN_RCVD    Received: contains a name with a faked IP-address
  284.  
  285. header SMTPD_IN_RCVD        Received =~ /\(SMTPD32-\d+\..+\)/
  286. describe SMTPD_IN_RCVD        Received via SMTPD32 server (SMTPD32-n.n)
  287.  
  288. header LOTS_OF_CC_LINES        eval:check_lots_of_cc_lines()
  289. describe LOTS_OF_CC_LINES    Lots and lots of Cc: headers
  290.  
  291. header FORGED_AOL_RCVD            eval:check_for_fake_aol_relay_in_rcvd()
  292. describe FORGED_AOL_RCVD    Received forged, contains fake AOL relays
  293.  
  294. header FORGED_TELESP_RCVD    Received =~ /\.(?!br).. \(\d+-\d+-\d+-\d+\.dsl\.telesp\.net\.br /
  295. describe FORGED_TELESP_RCVD    Contains forged hostname for a DSL IP in Brazil
  296.  
  297. # a forged Hotmail message; host HELO'd as hotmail.com, but it wasn't
  298. header FORGED_HOTMAIL_RCVD    eval:check_for_forged_hotmail_received_headers()
  299. describe FORGED_HOTMAIL_RCVD    Forged hotmail.com 'Received:' header found
  300.  
  301. # this, by comparison is more common: from was @hotmail.com, but it wasn't
  302. header FORGED_HOTMAIL_RCVD2    eval:check_for_no_hotmail_received_headers()
  303. describe FORGED_HOTMAIL_RCVD2 hotmail.com 'From' address, but no 'Received:'
  304.  
  305. header FORGED_EUDORAMAIL_RCVD    eval:check_for_forged_eudoramail_received_headers()
  306. describe FORGED_EUDORAMAIL_RCVD    Forged eudoramail.com 'Received:' header found
  307.  
  308. header FORGED_YAHOO_RCVD    eval:check_for_forged_yahoo_received_headers()
  309. describe FORGED_YAHOO_RCVD    'From' yahoo.com does not match 'Received' headers
  310.  
  311. header FORGED_JUNO_RCVD        eval:check_for_forged_juno_received_headers()
  312. describe FORGED_JUNO_RCVD    'From' juno.com does not match 'Received' headers
  313.  
  314. header FORGED_GW05_RCVD        eval:check_for_forged_gw05_received_headers()
  315. describe FORGED_GW05_RCVD    Forged 'by gw05' 'Received:' header found
  316.  
  317. # real hotmail outgoings use 'mc1-s3.law16...' or 'f206..' etc.
  318. header FORGED_MX_HOTMAIL    Received =~ /^from mx\d+\.hotmail\.com /m
  319. describe FORGED_MX_HOTMAIL    Forged hotmail.com Received 'from mx' header
  320.  
  321. # not used directly right now due to FPs; but CONFIRMED_FORGED turns it
  322. # into a 1.0 S/O rule anyway, so that's not a problem ;)
  323. # 2.626   3.6340   1.5251    0.704   0.34    1.44  FORGED_RCVD_TRAIL
  324. # 0.956   3.3890   0.0000    1.000   0.98    4.30  CONFIRMED_FORGED
  325. header __FORGED_RCVD_TRAIL    eval:check_for_forged_received_trail()
  326.  
  327. # forgery meta-rules: more reliable than their inputs
  328. meta CONFIRMED_FORGED        (__FORGED_RCVD_TRAIL && (FORGED_AOL_RCVD || FORGED_HOTMAIL_RCVD || FORGED_EUDORAMAIL_RCVD || FORGED_YAHOO_RCVD || FORGED_JUNO_RCVD || FORGED_GW05_RCVD || FORGED_MX_HOTMAIL))
  329. describe CONFIRMED_FORGED    Received headers are forged
  330.  
  331. meta MULTI_FORGED        ((FORGED_AOL_RCVD + FORGED_HOTMAIL_RCVD + FORGED_EUDORAMAIL_RCVD + FORGED_YAHOO_RCVD + FORGED_JUNO_RCVD + FORGED_GW05_RCVD) > 1)
  332. describe MULTI_FORGED        Received headers indicate multiple forgeries
  333.  
  334. # Sep 23 2002 jm: another spamhaus rule
  335. header RCVD_BY_QVES_COM        Received =~ /by email.qves.com with Microsoft/
  336. describe RCVD_BY_QVES_COM    Sent by a known spamhaus (qves)
  337.  
  338. header NONEXISTENT_CHARSET    Content-Type =~ /charset=.?DEFAULT/
  339. describe NONEXISTENT_CHARSET    Character set doesn't exist
  340.  
  341. header CHARSET_FARAWAY_HEADER        eval:check_for_faraway_charset_in_headers()
  342. describe CHARSET_FARAWAY_HEADER    A foreign language charset used in headers
  343. tflags CHARSET_FARAWAY_HEADER        userconf
  344.  
  345. header X_MAILER_GIBBERISH    X-Mailer =~ /^[A-Fa-f0-9\.]{48,}$/
  346. describe X_MAILER_GIBBERISH    'X-Mailer' line contains gibberish
  347.  
  348. header X_PRIORITY_HIGH        X-Priority =~ /^1/
  349. describe X_PRIORITY_HIGH    Sent with 'X-Priority' set to high
  350.  
  351. header X_MSMAIL_PRIORITY_HIGH    X-Msmail-Priority =~ /^High/
  352. describe X_MSMAIL_PRIORITY_HIGH    Sent with 'X-Msmail-Priority' set to high
  353.  
  354. header MANY_FROMS        From =~ /^[^\"\<\(]+, [^\"\<\(]+$/
  355. describe MANY_FROMS        'From' contains more than one address
  356.  
  357. # *so* many spams come from here.
  358. header BTAMAIL_HEADER        ALL =~ /\bbtamail\.net\.cn/i
  359. describe BTAMAIL_HEADER        Header contains an address from btamail.net.cn
  360.  
  361. header USER_IN_BLACKLIST    eval:check_from_in_blacklist()
  362. describe USER_IN_BLACKLIST    From: address is in the user's black-list
  363. tflags USER_IN_BLACKLIST        userconf
  364.  
  365. header USER_IN_WHITELIST    eval:check_from_in_whitelist()
  366. describe USER_IN_WHITELIST    From: address is in the user's white-list
  367. tflags USER_IN_WHITELIST        userconf nice
  368.  
  369. header USER_IN_DEF_WHITELIST    eval:check_from_in_default_whitelist()
  370. describe USER_IN_DEF_WHITELIST    From: address is in the default white-list
  371. tflags USER_IN_DEF_WHITELIST    userconf nice
  372.  
  373. # noticed this implied in passing in Dan's CVS messages. ;)  no nonspam hits
  374. # but only a small number of spam ones, for me.
  375. header HTML_ALL_CAPS           Content-Type =~ /TEXT\/HTML/
  376. describe HTML_ALL_CAPS        Content type is "TEXT/HTML" in all caps
  377.  
  378. # this variant is local, using the Received hdr itself...
  379. header ROUND_THE_WORLD_LOCAL    eval:check_for_round_the_world_received_helo()
  380. describe ROUND_THE_WORLD_LOCAL    Received: says mail sent around the world (HELO)
  381.  
  382. # and this one uses a DNS reverse lookup.  so now we can use a version
  383. # of this test without a net connection, or in mass-check etc.
  384. header ROUND_THE_WORLD        eval:check_for_round_the_world_received_revdns()
  385. describe ROUND_THE_WORLD    Received: says mail sent around the world (DNS)
  386. tflags ROUND_THE_WORLD          net
  387.  
  388. # this is a quite common false positive, as it's legal to remove a To but leave
  389. # a CC. so don't score it high.
  390. header MISSING_HEADERS        eval:check_for_missing_to_header()
  391. describe MISSING_HEADERS    Missing To: header
  392.  
  393. header SUSPICIOUS_RECIPS    eval:similar_recipients('0.6','1.2')
  394. describe SUSPICIOUS_RECIPS    Similar addresses in recipient list
  395.  
  396. header VERY_SUSP_RECIPS        eval:similar_recipients('1.2','undef')
  397. describe VERY_SUSP_RECIPS    Very similar addresses in recipient list 
  398.  
  399. header SORTED_RECIPS        eval:sorted_recipients()
  400. describe SORTED_RECIPS        Recipient list is sorted by address
  401.  
  402. header USER_IN_BLACKLIST_TO     eval:check_to_in_blacklist()
  403. describe USER_IN_BLACKLIST_TO   User is listed in 'blacklist_to'
  404. tflags USER_IN_BLACKLIST_TO     userconf nice
  405.  
  406. header USER_IN_WHITELIST_TO     eval:check_to_in_whitelist()
  407. describe USER_IN_WHITELIST_TO   User is listed in 'whitelist_to'
  408. tflags USER_IN_WHITELIST_TO     userconf nice
  409.  
  410. header USER_IN_MORE_SPAM_TO     eval:check_to_in_more_spam()
  411. describe USER_IN_MORE_SPAM_TO   User is listed in 'more_spam_to'
  412. tflags USER_IN_MORE_SPAM_TO     userconf nice
  413.  
  414. header USER_IN_ALL_SPAM_TO      eval:check_to_in_all_spam()
  415. describe USER_IN_ALL_SPAM_TO    User is listed in 'all_spam_to'
  416. tflags USER_IN_ALL_SPAM_TO      userconf nice
  417.  
  418. header GAPPY_SUBJECT        Subject =~ /\b(?:[a-z]([-_. =~\/:,*!\@\#\$\%\^&+;\"\'<>\\])\1{0,2}){4,}/i
  419. describe GAPPY_SUBJECT        Subject: contains G.a.p.p.y-T.e.x.t
  420.  
  421. ### header existence tests (description is added automatically)
  422.  
  423. # X-Fix example: NTMail fixed non RFC822 compliant EMail message
  424. #
  425. # X-PMFLAGS is all caps
  426. #
  427. # Headers that seem to only be used by a single spamming software and
  428. # are found together in the same message:
  429. # 1. X-MailingID and X-ServerHost
  430. # 2. X-Stormpost-To and X-List-Unsubscribe
  431. #
  432. # not spammish: X-EM-Registration, X-EM-Version, X-Antiabuse, X-List-Host,
  433. # X-Message-Id
  434. # bad FP rate: Comment, Date-warning
  435.  
  436. # slower version with same stats as of 2003-05-12
  437. # header X_LIST_UNSUBSCRIBE    X-List-Unsubscribe:addr =~ /\d{3}.*\d{3}.*\@/
  438. header X_LIST_UNSUBSCRIBE    exists:X-List-Unsubscribe
  439. describe X_LIST_UNSUBSCRIBE    Message has X-List-Unsubscribe header
  440.  
  441. # these headers have very high correlation with spam
  442. header X_ENC_PRESENT        exists:X-Encoding
  443. header X_ESMTP            exists:x-esmtp
  444. header X_LIBRARY        exists:X-Library
  445. header X_MAIL_ID_PRESENT    exists:X-MailingID
  446. header X_PMFLAGS_PRESENT    exists:X-PMFLAGS
  447. header X_PRECEDENCE_REF        exists:X-Precedence-Ref
  448. header X_SERV_HOST_PRESENT    exists:X-ServerHost
  449. header X_STORMPOST_TO        exists:X-Stormpost-To
  450. header X_X_PRESENT        exists:X-x
  451. header X_FIX_PRESENT            exists:X-Fix
  452. header COMPLAIN_TO        exists:Complain-To
  453. header X_VMP_TEXT               exists:X-VMP-Text
  454. header X_GCMULTI                exists:X-GCMulti
  455. header X_MIME_KEY        exists:X-Mime-Key
  456. header MICROSOFT        exists:microsoft
  457. describe X_ENC_PRESENT        Message has X-Encoding header
  458. describe X_ESMTP        Message has x-esmtp header
  459. describe X_LIBRARY        Message has X-Library header
  460. describe X_MAIL_ID_PRESENT    Message has X-MailingID header
  461. describe X_PMFLAGS_PRESENT    Message has X-PMFLAGS header
  462. describe X_PRECEDENCE_REF    Message has X-Precedence-Ref header
  463. describe X_SERV_HOST_PRESENT    Message has X-ServerHost header
  464. describe X_STORMPOST_TO        Message has X-Stormpost-To header
  465. describe X_X_PRESENT        Message has X-x header
  466. describe X_FIX_PRESENT        Message has X-Fix header
  467. describe COMPLAIN_TO        Message has Complain-To header
  468. describe X_VMP_TEXT        Message has X-VMP-Text header
  469. describe X_GCMULTI        Message has X-GCMulti header
  470. describe X_MIME_KEY        Message has X-Mime-Key header
  471. describe MICROSOFT        Message has microsoft header
  472.  
  473. header   MIME_ODD_CASE        ALL =~ /\nMiME-Version: /s
  474. describe MIME_ODD_CASE        MiME-Version header (oddly capitalized)
  475.  
  476. header   __HAS_MIMEOLE          exists:X-MimeOLE
  477. header   __HAS_MSMAIL_PRI       exists:X-MSMail-Priority
  478. header   __HAS_SQUIRRELMAIL_IN_MAILER    X-Mailer =~ /SquirrelMail\b/
  479. meta     MISSING_MIMEOLE    (__HAS_MSMAIL_PRI && !__HAS_MIMEOLE && !__HAS_SQUIRRELMAIL_IN_MAILER)
  480. describe MISSING_MIMEOLE    Message has X-MSMail-Priority, but no X-MimeOLE
  481.  
  482. header __HAS_X_MAILER        exists:X-Mailer
  483. header __HAS_OUTLOOK_IN_MAILER    X-Mailer =~ /Microsoft (CDO|Outlook|Office Outlook)\b/
  484. meta MISSING_OUTLOOK_NAME    ((__HAS_MIMEOLE || __HAS_MSMAIL_PRI) && __HAS_X_MAILER && !__HAS_OUTLOOK_IN_MAILER && !__HAS_SQUIRRELMAIL_IN_MAILER)
  485. describe MISSING_OUTLOOK_NAME    Message looks like Outlook, but isn't
  486.  
  487. header   __HAS_X_PRIORITY       exists:X-Priority
  488. meta     PRIORITY_NO_NAME    ((__HAS_X_PRIORITY || __HAS_MSMAIL_PRI) && !__HAS_X_MAILER)
  489. describe PRIORITY_NO_NAME    Message has priority setting, but no X-Mailer
  490.  
  491. header SUBJ_AS_SEEN        Subject =~ /\bAs Seen/i
  492. describe SUBJ_AS_SEEN        Subject contains "As Seen"
  493.  
  494. header SUBJ_DOLLARS             Subject =~ /^\$[0-9.,]+\b/
  495. describe SUBJ_DOLLARS           Subject starts with dollar amount
  496.  
  497. header SUBJ_DOUBLE_YOUR        Subject =~ /Double Your/i
  498. describe SUBJ_DOUBLE_YOUR    Subject contains "Double Your"
  499.  
  500. header SUBJ_FOR_ONLY         Subject =~ /For Only/i
  501. describe SUBJ_FOR_ONLY         Subject contains "For Only"
  502.  
  503. header SUBJ_FREE_CAP        Subject =~ /FRE{2,}|F.R.E.E\b/
  504. describe SUBJ_FREE_CAP        Subject contains "FREE" in CAPS
  505.  
  506. header SUBJ_FREE_INSTANT     Subject =~ /Free Instant/i
  507. describe SUBJ_FREE_INSTANT     Subject contains "Free Instant"
  508.  
  509. header SUB_FREE_OFFER           Subject =~ /^fre{2,}\b/i
  510. describe SUB_FREE_OFFER         Subject starts with "Free"
  511.  
  512. header SUBJ_GUARANTEED          Subject =~ /^guaranteed|(?-i:GUARANTEE)/i
  513. describe SUBJ_GUARANTEED        Subject GUARANTEED
  514.  
  515. header SUB_HELLO                Subject =~ /^hello\b/i
  516. describe SUB_HELLO              Subject starts with "Hello"
  517.  
  518. header SUBJ_LIFE_INSURANCE    Subject =~ /life\s+insurance/i
  519. describe SUBJ_LIFE_INSURANCE    Subject includes "life insurance"
  520.  
  521. header SUBJ_NOW_ONLY        Subject =~ /\bNow Only/i
  522. describe SUBJ_NOW_ONLY        Subject contains "Now Only"
  523.  
  524. header SUBJ_RIPPED        Subject =~ /Ripped & Strong/i
  525. describe SUBJ_RIPPED        Subject contains "Ripped & Strong"
  526.  
  527. header SUBJ_VIAGRA        Subject =~ /viagra/i
  528. describe SUBJ_VIAGRA        Subject includes "viagra"
  529.  
  530. header SUBJ_YOUR_DEBT        Subject =~ /Your (?:Bills|Debt|Credit)/i
  531. describe SUBJ_YOUR_DEBT        Subject contains "Your Bills" or similar
  532.  
  533. header SUBJ_YOUR_FAMILY        Subject =~ /Your Family/i
  534. describe SUBJ_YOUR_FAMILY    Subject contains "Your Family"
  535.  
  536. header SUBJ_YOUR_OWN        Subject =~ /Your Own/i
  537. describe SUBJ_YOUR_OWN        Subject contains "Your Own"
  538.  
  539. header VAR_REF_IN_RECEIVED      Received =~ /from \$\S+ \(/
  540. describe VAR_REF_IN_RECEIVED    Received contains a $variable reference
  541.  
  542. # the real services never HELO as 'foo.com', instead 'mail.foo.com' or
  543. # something like that.  Note: be careful when expanding this... legit dotcom
  544. # HELOers include: hotmail.com, drizzle.com, lockergnome.com.
  545. header RCVD_FAKE_HELO_DOTCOM    Received =~ /^from (?:msn|yahoo|yourwebsite|lycos|excite|cs|aol|localhost|koreanmail|allexecs|mydomain|juno|eudoramail|compuserve|desertmail|excite|caramail)\.com \(/m
  546. describe RCVD_FAKE_HELO_DOTCOM  Received contains a faked HELO hostname
  547.  
  548. header USERNAME_IN_SUBJECT    eval:check_for_to_in_subject()
  549. describe USERNAME_IN_SUBJECT    To: username at front of subject
  550.  
  551. header LOSE_POUNDS              Subject =~ /\bLose .*(?:pounds|lbs|weight)/i
  552. describe LOSE_POUNDS            Subject talks about losing pounds
  553.  
  554. header EXTRA_MPART_TYPE         Content-Type =~ /(?:\s*multipart\/)?.* type=/i
  555. describe EXTRA_MPART_TYPE       Header has extraneous Content-type:...type= entry
  556.  
  557. header TO_RECIP_MARKER          To =~ /\#recipient\#/
  558. describe TO_RECIP_MARKER        To header contains 'recipient' marker
  559.  
  560. header SAVINGS            Subject =~ /\bsave\s+(?:on\s+your|up\s+to|big|over|at\s+least|\d+\%|you)(?:\s|\b|$)/i
  561. describe SAVINGS        Subject talks about savings
  562.  
  563. # MIME boundary tests; spam tools use distinctive patterns.
  564. header MIME_BOUND_DASH_DIGIT    Content-Type =~ /boundary="_-{10}=_\d{19,22}"/
  565. describe MIME_BOUND_DASH_DIGIT    Spam tool pattern in MIME boundary
  566. header MIME_BOUND_HASHES    Content-type =~ /boundary=\"\#{10}\"/
  567. describe MIME_BOUND_HASHES    Spam tool pattern in MIME boundary
  568. header MIME_BOUND_DIGITS_4    Content-Type =~ /boundary=\"_----------=_\d{18}\"/
  569. describe MIME_BOUND_DIGITS_4    Spam tool pattern in MIME boundary
  570. header MIME_BOUND_DIGITS_7    Content-Type =~ /boundary=\d{9}\.\d{13}/
  571. describe MIME_BOUND_DIGITS_7    Spam tool pattern in MIME boundary
  572. header MIME_BOUND_HEX_24    Content-Type =~ /boundary=\"[\dA-F]{24}\"/
  573. describe MIME_BOUND_HEX_24    Spam tool pattern in MIME boundary
  574. header MIME_BOUND_MA        Content-Type =~ /boundary=\"----=_[a-zA-Z0-9]{8}_[a-zA-Z0-9]{8}_MA\"/
  575. describe MIME_BOUND_MA        Spam tool pattern in MIME boundary
  576. header MIME_BOUND_MANY_HEX    Content-Type =~ /boundary="[\da-f]{8}(?:-[\da-f]{4}){3}-[\da-f]{12}"/
  577. describe MIME_BOUND_MANY_HEX    Spam tool pattern in MIME boundary
  578. header __NEXTPART_ALL        Content-Type =~ /NextPart/
  579. header __NEXTPART_NORMAL    Content-Type =~ /="(?:----_?=_)?NextPart_[\dA-F]{3}(_[\dA-F]{3,8})?_[\dA-F]{8}\.[\dA-F]{8}"/
  580. meta MIME_BOUND_NEXTPART    (__NEXTPART_ALL && !__NEXTPART_NORMAL)
  581. describe MIME_BOUND_NEXTPART    Spam tool pattern in MIME boundary
  582. header MIME_BOUND_OPTIN        Content-Type =~ /boundary=\"[A-F\d]{8}-[A-F\d]{4}-[A-F\d]{4}-[A-F\d]{4}-[A-F\d]{12}OPTIN\"/
  583. describe MIME_BOUND_OPTIN    Spam tool pattern in MIME boundary
  584. header MIME_BOUND_MAIL_BOUND    Content-Type =~ /boundary=\"____MAIL_BOUNDARY____\"/
  585. describe MIME_BOUND_MAIL_BOUND    Spam tool pattern in MIME boundary
  586. header MIME_BOUND_TEP        Content-Type =~ /boundary="TEP-\d{9,10}\.\d{10}\.\d{10}"/
  587. describe MIME_BOUND_TEP        Spam tool pattern in MIME boundary
  588. header MIME_BOUND_RKFINDY       Content-Type =~ /boundary=\"=_NextPart_2rfkindysadvnqw3nerasdf\"/
  589. describe MIME_BOUND_RKFINDY     Spam tool pattern in MIME boundary (rfkindy)
  590.  
  591. header DATE_MISSING             Date =~ /^UNSET$/ [if-unset: UNSET]
  592. describe DATE_MISSING           Missing Date: header
  593.  
  594. # freqs:  0.001    0.003    0.000    1.00    2.66  POST_IN_RCVD
  595. header POST_IN_RCVD             Received =~ / Post\.(?:sk|cz)/  
  596. describe POST_IN_RCVD           Received contains fake 'Post.cz' hostname
  597.  
  598. header TO_INVESTORS             To =~ /\bInvestors\@/
  599. describe TO_INVESTORS           To: non-existent 'Investors' address
  600.  
  601. header TO_MALFORMED             To !~ /(?:(?:\"[^\"]+\"|\S+)\@\S+\.\S+|^\s*.+:\s*;|^\s*\"[^\"]+\":\s*;|^\s*\([^\)]*\)\s*$|<\S+(?:\!\S+){1,}>|^\s*$)/ [if-unset: unset@unset.unset]
  602. describe TO_MALFORMED           To: has a malformed address
  603.  
  604. # jm: somehow these guys keep slipping through, and they're very persistent.
  605. # they use both azoogle.com and azogle.com, but this header is always
  606. # in this format.
  607. header AZOOGLE            X-Info =~ /service to abuse\@azoogle\.com$/
  608. describe AZOOGLE        From azoogle.com, azogle.com, etc.
  609.  
  610. header SUBJECT_APPROVED        Subject =~ /approv(?:ed|al).?[.!*]/i
  611. describe SUBJECT_APPROVED    Subject talks about being approved
  612.  
  613. header SUBJ_HAS_TIME_ID         Subject =~ /\sTime[: ]+\d+:\d+:\d+ [AP]M\s*$/i
  614. describe SUBJ_HAS_TIME_ID       Subject has a Time ID
  615.  
  616. header __OPT_HEADER_SUBJ    ALL =~ /^(?:Resent-)?Subject:.*opt.?(in|out|oem|ed|ion-in|[\d@])(?:\b|\d|\@)/im
  617. header __OPT_HEADER_ALL        ALL =~ /opt.?(?:in|out|oem|ed|ion-in|[\d@])(?:\b|\d|\@)/i
  618. meta OPT_HEADER            (__OPT_HEADER_ALL && !__OPT_HEADER_SUBJ)
  619. describe OPT_HEADER        Headers include an "opt"ed phrase
  620.  
  621. # Most/all of these require that From addresses do not start with numbers.
  622. header FROM_NUM_AT_WEBMAIL    From:addr =~ /^\d\S+\@(?:msn\.com|flashmail\.com|mailexcite\.com|prodigy\.net|yahoo\.\S+|hotmail\.com|eudoramail\.com|aol\.com|excite\.com|email\.com|earthlink\.net|geocities\.com|hknetmail\.com|angelfire\.com)/i
  623. describe FROM_NUM_AT_WEBMAIL    From address is webmail, but starts with a number
  624.  
  625. header FROM_WEBMAIL_END_NUMS6    From:addr =~ /\d\d\d\d\d\d\@(?:aol|msn|bigfoot|compuserve|excite|hotmail|juno|prodigy|yahoo)\.(?:com|net|org)/i
  626. describe FROM_WEBMAIL_END_NUMS6    From webmail service and address ends in numbers
  627.  
  628. header ADDR_FREE              From =~ /\b(?-i:F)ree(?-i:[ A-Z]).*</i
  629. describe ADDR_FREE            From Address contains FREE
  630.  
  631. # thanks to Jason Staples for this suggestion. Sendmail and other MTAs
  632. # will often query the ident server on a relay; Squid proxies should not be
  633. # sending mail.
  634. header RECEIVED_IDENT_SQUID        Received =~ /ident[:=]squid\b/i
  635. describe RECEIVED_IDENT_SQUID        Message was sent by a Squid HTTP proxy
  636. header RECEIVED_CACHEFLOW        Received =~ /CacheFlowServer/
  637. describe RECEIVED_CACHEFLOW    Received contains 'CacheFlowServer' IDENT name
  638.  
  639. # common spam-dropping: To: C:\VICTIMS.txt@yourmx.org
  640. header TO_TXT            To =~ /\.txt[\'\"]?\@/i
  641. describe TO_TXT            Sent to a text file
  642.  
  643. header CHINA_HEADER             ALL =~ /\@china\.com/i
  644. describe CHINA_HEADER           Involves 'china.com'
  645.  
  646. header __CD                     exists:Content-Disposition
  647. header __CT                     exists:Content-Type
  648. header __CTE                    exists:Content-Transfer-Encoding
  649. header __MIME_VERSION           exists:MIME-Version
  650. header __CT_TEXT_PLAIN          Content-Type =~ /^text\/plain\b/i
  651. meta MIME_HEADER_CTYPE_ONLY     (!__CD && !__CTE && __CT && !__MIME_VERSION && !__CT_TEXT_PLAIN)
  652. describe MIME_HEADER_CTYPE_ONLY 'Content-Type' found without required MIME headers
  653.  
  654. header WITH_LC_SMTP        Received =~ /\swith\ssmtp;\s/
  655. describe WITH_LC_SMTP        Received line contains spam-sign (lowercase smtp)
  656.  
  657. header FROM_NO_LOWER        From !~ /[a-z]/
  658. describe FROM_NO_LOWER          'From' has no lower-case characters
  659.  
  660. header SUBJ_BUY                 Subject =~ /^buy/i
  661. describe SUBJ_BUY               'Subject' starts with Buy, Buying
  662.  
  663. header __FROM_HAS_UNDERLINE_NUMS    From =~ /_\S?(?:[a-z]+\w*?\d+|\d+\w*?[a-z]+)\w*\@/i
  664. meta FROM_HAS_ULINE_NUMS        (!REPLY_TO_ULINE_NUMS && __FROM_HAS_UNDERLINE_NUMS)
  665. describe FROM_HAS_ULINE_NUMS    From: contains an underline and numbers/letters
  666.  
  667. header NIGERIAN_SUBJECT1    Subject =~ /^(?:Re:|\[.{1,10}\])?\s*(?:(?:very )?URGENT|ATTENTION)\s*$/i
  668. describe NIGERIAN_SUBJECT1    Subject is indicative of a Nigerian spam
  669. header NIGERIAN_SUBJECT2    Subject =~ /^(?:Re:|\[.{1,10}\])?\s*(?:very )?urgent\s+(?:(?:and|&)\s+)?(?:confidential|assistance|business|attention|reply|response|help)\b/i
  670. describe NIGERIAN_SUBJECT2    Subject is indicative of a Nigerian spam
  671. header NIGERIAN_SUBJECT6    Subject =~ /^(?:Re:|\[.{1,10}\])?\s*(?:family )?assis?tance\s*$/i
  672. describe NIGERIAN_SUBJECT6    Subject is indicative of a Nigerian spam
  673.  
  674. # this code uses an access database (sendmail, postfix, etc.)
  675. # Since you need to actively create an accessdb to use it, the rule is
  676. # considered userconf and is disabled by default.
  677. header ACCESSDB            eval:check_access_database('/etc/mail/access.db')
  678. describe ACCESSDB        Message would have been caught by accessdb
  679. tflags ACCESSDB            userconf
  680.  
  681. # via private mail with Mark Delany; thx Mark!
  682. header FORGED_YAHOO_RCVD_SMTP    Received =~ /from smtp(?:\d{1,2}|\d{4,})\.mail(?:\.[^\.]+|)\.yahoo\.com /
  683. describe FORGED_YAHOO_RCVD_SMTP  Header contains forged Yahoo! SMTP server hostname
  684.  
  685. # a new spamware tool; catch it
  686. header FORGED_RCVD_FROM_NUM    Received =~ /from \S+ \(\d+ \[/
  687. describe FORGED_RCVD_FROM_NUM    Received headers forged (numeric hostname)
  688.  
  689. # seems to be ratware
  690. header RCVD_AM_PM        Received =~ /; [A-Z][a-z][a-z], \d{1,2} \d{4} \d{1,2}:\d\d:\d\d [AP]M [+-]\d{4}/
  691. describe RCVD_AM_PM        Received headers forged (AM/PM)
  692.  
  693. header RATWARE_EMPTY_HELO    Received =~ /from  \(\) by /
  694. describe RATWARE_EMPTY_HELO    Received headers forged (empty HELO)
  695.  
  696. header TO_FILENAME        To =~ /<[CDEF]:/
  697. describe TO_FILENAME        "To" header contains a filename
  698.  
  699. # quinlan: 2003-03-10, updated 2003-03-22
  700. # reply to a numbered address
  701. header ID_REPLY_TO_REPLY    Reply-To:addr =~ /reply.*\d{4}.*\@/i
  702. describe ID_REPLY_TO_REPLY    Reply-To address with reply and numbers
  703.  
  704. # unsubscribe from a numbered address
  705. header __ID_REPLY_TO        Reply-To:addr =~ /\d{3}.*\d{3}.*\@/
  706. header __ID_RETURN_PATH        Return-path:addr =~ /\d{3}.*\d{3}.*\@/
  707. meta ID_UNIQUE            (X_LIST_UNSUBSCRIBE && __ID_RETURN_PATH && __ID_REPLY_TO)
  708. describe ID_UNIQUE        X-List-Unsubscribe has a numbered address
  709.  
  710. # 2003-04-12
  711. # juno.com anti-forgery rule based on valid juno.com account names
  712. # reference: http://www.juno.com/legal/spam.html
  713. # quinlan: not a lot of hits for me, but maybe it will work better for others
  714. header __JUNO_FROM        From:addr =~ /\@juno\.com\b/i
  715. # more restrictive interpretation of their valid account name rules,
  716. # don't allow any of the permitted non-alphanumeric characters to be
  717. # repeated, this should probably be verified
  718. header __JUNO_FROM_VALID    From:addr =~ /^[a-z](?:[a-z0-9]|[-._](?![-._])){0,62}[a-z0-9]\@juno\.com\b/i
  719. meta FORGED_JUNO_FROM        (__JUNO_FROM && !__JUNO_FROM_VALID)
  720. describe FORGED_JUNO_FROM    Has invalid account name for juno.com address
  721.  
  722. header HEADER_COUNT_CTYPE    eval:check_header_count_range('Content-Type','2','999')
  723. describe HEADER_COUNT_CTYPE    Multiple Content-Type headers found
  724.  
  725. # pretty good spamware sign, looks like it uses random numbers with no padding
  726. #   Message-Id: <\d{1,3}\.\d{1,6}\.\d{1,6}@\S+>h
  727. #   usually also has INVALID_DATE and NO_REAL_NAME
  728. # this rule excludes about 0.02% of matches since some low random
  729. # numbers in the second or third part will be missed.
  730. header MSGID_THREESIXSIX    Message-Id =~ /<\d{1,3}\.\d{3,6}\.\d{3,6}\@\S+>/
  731. describe MSGID_THREESIXSIX    Message-Id header indicates message is spam
  732.  
  733. header __USER_AGENT_MSN             X-Mailer =~ /^MSN Explorer /
  734.  
  735. # hmm, interesting.   Ensure the MUA is using consistent priorities.
  736. # http://www3.cds.ne.jp/~marimo/oka/research/em/data0002.html
  737. header __X_PRI_HI               X-Priority =~ /^[12]/
  738. header __X_MSPRI_HI             X-Msmail-Priority =~ /^High/
  739. meta X_PRI_MISMATCH_HI            (__X_PRI_HI && __HAS_MSMAIL_PRI && !__X_MSPRI_HI)
  740. describe X_PRI_MISMATCH_HI    'X-Priority' does not match 'X-MSMail-Priority'
  741.  
  742. header FORGED_RCVD_NET_HELO    eval:check_for_forged_received_ip_helo()
  743. describe FORGED_RCVD_NET_HELO    Host HELO'd using the wrong IP network
  744.  
  745. header NO_RDNS_DOTCOM_HELO    eval:check_for_no_rdns_dotcom_helo()
  746. describe NO_RDNS_DOTCOM_HELO    Host HELO'd as a big ISP, but had no rDNS
  747.  
  748. header X_ORIG_HOST        X-Originating-Host =~ /^\[/
  749. describe X_ORIG_HOST        Message has X-Originating-Host header
  750.  
  751. # Hotmail's DAV interface uses this and it's heavily exploited right now.  As
  752. # far as I can tell, it requires an msn.com or hotmail.com X-Originating-Email:
  753. # but allows anything for From: so use that as a spamsign.
  754. header __HAS_MSN_RCVD_DAV    Received =~ / by \S+\.(?:hotmail|msn)\.com with (?:HTTP|DAV)\;/
  755. header __HAS_MSN_ORIG_EMAIL    X-Originating-Email =~ /(?:hotmail|msn)\.com\b/
  756. header __HAS_MSN_FROM        From =~ /(?:hotmail|msn)\.com\b/
  757. meta FAKED_HOTMAIL_DAV        (__HAS_MSN_RCVD_DAV && __HAS_MSN_ORIG_EMAIL && !__HAS_MSN_FROM)
  758. describe FAKED_HOTMAIL_DAV    X-Originating-Email header does not match From
  759.  
  760.